<template>
	<view class="sign-wrap">
		<u-popup ref="popup" type="center" :mask-click="false" safe-area>
			<view class="sign-box">
				<canvas class="canvas" :canvasId="ctx.cid" :id="ctx.cid"
					:style="{width: '375px', height: screenHeight + 'px'}" @touchstart="onTouchStart"
					@touchmove="onTouchMove" @touchend="onTouchEnd" disable-scroll></canvas>
				<view class="popup-buttons">
					<view class="bottom-left" @click="close">取消</view>
					<view class="bottom-right" @click="saveImage">确定</view>
				</view>
				<canvas class="mycanvas" :style="{ 'z-index': -1}" id="rotatCanvas" canvas-id="rotatCanvas"></canvas>
			</view>
		</u-popup>
	</view>
</template>

<script>
	import {
		pathToBase64
	} from 'image-tools'
	export default {
		data() {
			return {
				ctx: {
					cid: null,
					instance: undefined,
					lineData: []
				},
				screenHeight: null
			}
		},
		props: {
			backgroundColor: {
				type: String,
				default: '#fff'
			}
		},
		mounted() {
			this.ctx.cid = new Date().getTime().toString()
			this.init()
		},
		methods: {
			init() {
				this.ctx.instance = uni.createCanvasContext(this.ctx.cid, this);
				uni.getSystemInfo({
					success: e => {
						this.screenHeight = e.screenHeight - 150;
						this.setBackgroundColor(this.backgroundColor)
					}
				});
			},
			onTouchStart(e) {
				const pos = e.touches[0];
				this.ctx.lineData.push({
					style: {
						color: '#000',
						width: 5
					},
					// 屏幕坐标
					coordinates: [{
						type: e.type,
						x: pos.x,
						y: pos.y
					}]
				})
				this.drawLine()
			},
			onTouchMove(e) {
				const pos = e.touches[0]
				this.ctx.lineData[this.ctx.lineData.length - 1].coordinates.push({
					type: e.type,
					x: pos.x,
					y: pos.y
				})
				this.drawLine()
			},
			onTouchEnd(e) {
				this.$emit('end', this.ctx.lineData)
			},
			// 清空画布
			clear() {
				this.ctx.lineData = []
				this.ctx.instance.clearRect(0, 0, 375, this.screenHeight)
				this.ctx.instance.draw()
				this.setBackgroundColor(this.backgroundColor)
				this.$emit('clear')
			},
			// 撤销
			revoke() {
				this.setBackgroundColor(this.backgroundColor)
				this.ctx.lineData.pop()
				this.ctx.lineData.forEach((item, index) => {
					this.ctx.instance.beginPath()
					this.ctx.instance.setLineCap('round')
					this.ctx.instance.setStrokeStyle(item.style.color)
					this.ctx.instance.setLineWidth(item.style.width)
					if (item.coordinates.length < 2) {
						const pos = item.coordinates[0]
						this.ctx.instance.moveTo(pos.x, pos.y)
						this.ctx.instance.lineTo(pos.x + 1, pos.y)
					} else {
						item.coordinates.forEach(pos => {
							if (pos.type == 'touchstart') {
								this.ctx.instance.moveTo(pos.x, pos.y)
							} else {
								this.ctx.instance.lineTo(pos.x, pos.y)
							}
						})
					}
					this.ctx.instance.stroke()
				})
				this.ctx.instance.draw(true)
				this.$emit('revoke', this.ctx.lineData)
			},
			// 绘制线条
			drawLine() {
				const lineDataLen = this.ctx.lineData.length
				if (!lineDataLen) return
				const currentLineData = this.ctx.lineData[lineDataLen - 1]
				const coordinates = currentLineData.coordinates
				const coordinatesLen = coordinates.length
				if (!coordinatesLen) return
				let startPos
				let endPos
				if (coordinatesLen < 2) {
					// only start, no move event
					startPos = coordinates[coordinatesLen - 1]
					endPos = {
						x: startPos.x + 1,
						y: startPos.y
					}
				} else {
					startPos = coordinates[coordinatesLen - 2]
					endPos = coordinates[coordinatesLen - 1]
				}

				const style = currentLineData.style
				this.ctx.instance.beginPath()
				this.ctx.instance.setLineCap('round')
				this.ctx.instance.setStrokeStyle(style.color)
				this.ctx.instance.setLineWidth(style.width)
				this.ctx.instance.moveTo(startPos.x, startPos.y)
				this.ctx.instance.lineTo(endPos.x, endPos.y)
				this.ctx.instance.stroke()
				this.ctx.instance.draw(true)
			},
			close() {
				this.clear();
				this.$refs.popup.close();
			},
			async saveImage(filename = '签名') {
				const tempFilePath = await this.canvasToTempFilePath();
				this.$emit('sign-data', tempFilePath)
				this.clear();
				this.$refs.popup.close();
				// pathToBase64(tempFilePath).then((path) => {
				// 	this.$emit('sign-data', path)
				// 	this.clear();
				// 	this.$refs.popup.close();
				// })
			},
			// canvas 保存为临时图片路径，h5返回 base64
			canvasToTempFilePath(conf = {}) {
				return new Promise((resolve, reject) => {
					uni.canvasToTempFilePath({
							canvasId: this.ctx.cid,
							width: 375,
							height: this.screenHeight,
							...conf,
							success: res => {
								uni.getImageInfo({
									// 获取图片的信息
									src: res.tempFilePath,
									success: (res1) => {
										// 将canvas1的内容复制到canvas2中
										let canvasContext = uni.createCanvasContext(
											'rotatCanvas',
											this)
										let rate = res1.height / res1.width
										let width = 300 / rate
										let height = 300
										canvasContext.setFillStyle('#FFFFFF')
										canvasContext.fillRect(0, 0, res1.width, res1.height)
										// canvasContext.fill()
										canvasContext.translate(height / 2, width / 2)
										canvasContext.rotate((270 * Math.PI) / 180)
										canvasContext.drawImage(res.tempFilePath, -width / 2, -
											height /
											2, width, height)
										canvasContext.draw(false, (data) => {
											// 将之前在绘图上下文中的描述（路径、变形、样式）画到 canvas 中
											uni.canvasToTempFilePath({
												// 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
												canvasId: 'rotatCanvas',
												fileType: 'png',
												quality: 1, //图片质量
												success: (res2) => {
													resolve(res2
														.tempFilePath);
												}
											}, this)
										});
									}
								})
							},
							fail: err => {
								reject(err)
							}
						},
						this
					)
				})
			},
			setBackgroundColor(color = '#fff') {
				this.ctx.instance.beginPath()
				this.ctx.instance.setFillStyle(color)
				this.ctx.instance.fillRect(0, 0, 375, this.screenHeight)
				this.ctx.instance.fill()
				this.ctx.instance.draw(true)
			},
			open() {
				this.$refs.popup.open();
			}
		}
	}
</script>

<style lang="scss" scoped>
	.sign-wrap {
		height: 100%;
		background-color: #FFFFFF;

		.sign-box {
			width: 750rpx;
			height: 100%;
			background-color: #FFFFFF;
			position: relative;

			.canvas {
				margin-bottom: 300rpx;
			}

			.mycanvas {
				position: absolute;
				z-index: -11;
			}

			.popup-buttons {
				transform: rotate(90deg);
				margin-top: 20rpx;
				position: fixed;
				width: 350rpx;
				left: -40rpx;
				bottom: -40rpx;
				display: block;

				.bottom-left,
				.bottom-right {
					width: 150rpx;
					line-height: 75rpx;
					font-size: 26rpx;
					text-align: center;
				}
				
				.bottom-right {
					background-color: #fff;
					border: 1rpx solid #F86165;
					color: #F86165;
				}

				.bottom-left {
					margin-bottom: 20rpx;
				}
			}
		}
	}
</style>